package com.jy.api.domain;

import com.jy.api.enums.OrderItemMakeType;
import com.jy.api.enums.OrderPayChannel;
import com.jy.api.exception.MyException;
import com.jy.api.signUpReq.ScanCodeSignUpReq;
import com.jy.api.signUpReq.pos.OrderItemSignUpReq;
import com.jy.api.signUpReq.pos.PaymentSignUpReq;
import com.jy.api.util.JodaUtils;
import com.jy.api.util.Md5Util;
import com.jy.api.util.MyDateUtils;
import com.jy.api.util.UuidUtil;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.hibernate.annotations.Where;

import javax.persistence.*;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by hanxi on 2017/7/17.
 * 订单表
 */
@Slf4j
@Entity
@Data
@NoArgsConstructor
public class Order implements Serializable {
    @Id
    @Column(length = 50)
    private String id;

    @Version
    protected int version = 0;
    private String storeId;
    private String memberId;
    private String memberName;
    private String creatorId;
    private String creatorName;
    private String code;
    private double total = 0;
    private int count = 0;
    private double discount = 0;
    private double amount = 0;
    @Enumerated(EnumType.STRING)
    private OrderStatus status;
    @Enumerated(EnumType.STRING)
    private OrderSource source;
    @Enumerated(EnumType.STRING)
    private OrderType type;
    @Temporal(TemporalType.TIMESTAMP)
    private Date createTime;

    private double removeZero;
    @Enumerated(EnumType.STRING)
    private OrderPayChannel payChannel;

    private String mobileTag;

    /**
     * 退单时间
     *
     * @deprecated 退单会生成新的订单记录，不允许修改已有订单
     */
    @Temporal(TemporalType.TIMESTAMP)
    private Date refundTime;

    @OneToMany(cascade = CascadeType.ALL, orphanRemoval = true)
    @Where(clause = "`enabled`=1")
    @OrderBy(value = "addTime")
    @JoinColumn(name = "order_id")
    private List<OrderItem> items = new ArrayList<>();

    /**
     * 座位号
     */
    private String tableNo;
    @Column(insertable = false, updatable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private Date addTime;
    @Column(insertable = false, updatable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private Date updateTime;
    private boolean enabled = true;
    /**
     * 固定提成金额
     */
    private double commission = 0;

    /**
     * 支付ID
     */
    private String payId;
    /**
     * 支付时间
     */
    private Date paymentTime;
    /**
     * 支付渠道
     */
    private String channel;

    /**
     * 商品出入库状态
     */
    private boolean stock = false;

    /**
     * 备注
     */
    private String notes;

    @ApiModelProperty("优惠券折扣金额")
    private double couponDiscountAmount;


    /**
     * 退单原因
     */
    private String refundReason;

    /**
     * 关联订单id。比如退单的原始订单id
     */
    private String refOrderId;

    private String payOrderId;


    //初始化订单
    public Order(String id, String creatorId, String creatorName) {
        this.id = id;
        this.creatorId = creatorId;
        this.creatorName = creatorName;
        this.status = OrderStatus.FINISHED;
        this.source = OrderSource.POS;
        this.type = OrderType.SALES;
        this.createTime = new Date();
        this.stock = true;
    }

    //初始化会员充斥订单
    public Order(String id, String storeId, String creatorId, String creatorName,
                 String productId, String productName, double amount,
                 double depositAmount, double salesPrice) {

        amount = Math.rint(amount * 100) / 100d;
        depositAmount = Math.rint(depositAmount * 100) / 100d;
        salesPrice = Math.rint(salesPrice * 100) / 100d;
        this.id = id;
        this.code = Md5Util.encrypt16(id);
        this.storeId = storeId;
        this.creatorId = creatorId;
        this.creatorName = creatorName;
        this.status = OrderStatus.INIT;
        this.source = OrderSource.POS;
        this.type = OrderType.MEMBER_DEPOSIT;
        this.amount = amount;
        this.total = depositAmount + amount;
        this.discount = depositAmount;
        this.count = 1;
        this.createTime = new Date();
        if (StringUtils.isNotBlank(productId)) {
            OrderItem orderItem = new OrderItem(UuidUtil.getUuid(),
                    productId, productName, salesPrice, amount,
                    1, 0, "");
            this.items.add(orderItem);
        }
    }

    //初始化订单
    public Order(String id, String storeId, String creatorId, String creatorName,
                 OrderSource source, Date createTime) {
        this.id = id;
        this.storeId = storeId;
        this.creatorId = creatorId;
        this.creatorName = creatorName;
        this.status = OrderStatus.INIT;
        this.source = source;
        this.type = OrderType.SALES;
        this.createTime = createTime;
    }


    public OrderItem  getOneItem(String orderItemId) {
        for (OrderItem item : items) {
            if (item.getId().equals(orderItemId)){
                return item;
            }
        }
        return null;
    }

    //初始化订单
    public Order(String id, String storeId, String creatorId, String creatorName,
                 OrderSource source, double amount, String payId, Date createTime) {
        this.id = id;
        this.storeId = storeId;
        this.creatorId = creatorId;
        this.creatorName = creatorName;
        this.status = OrderStatus.FINISHED;
        this.source = source;
        this.type = OrderType.SALES;
        this.createTime = new Date();
        this.amount = amount;
        this.count = 1;
        this.discount = 0.0;
        this.paymentTime = createTime;
        this.payId = payId;
        this.total = amount;
    }

    /**
     * 添加商品明细
     *
     * @param product
     * @param quantity
     */
    public void addItem(Product product, int quantity) {
        double price = Math.rint(product.getSalesPrice() * quantity * 100) / 100d;
        double costPrice = Math.rint(quantity * product.getCostPrice() * 100) / 100d;
        double commission = Math.rint(quantity * product.getCommission() * 100) / 100d;
        amount += price;
        total += price;
        count += quantity;
        this.commission += commission;
        Boolean check = true;
        //查看同类商品是否已选中
        for (OrderItem item : items) {
            if (StringUtils.equals(item.getProductId(), product.getId())) {
                item.setSalesPrice(item.getSalesPrice() + price);
                item.setDealPrice(item.getDealPrice() + price);
                item.setQuantity(item.getQuantity() + quantity);
                item.setCostPrice(item.getCostPrice() + costPrice);
                item.setCommission(item.getCommission() + commission);
                check = false;
                item.accuracy();
                break;

            }
        }
        //不存在新增订单明细
        if (check) {
            OrderItem item = new OrderItem(UuidUtil.getUuid(), product, price, price, quantity, commission);
            item.setCostPrice(item.getCostPrice() + costPrice);
            item.setKitchenPrintEnabled(false);
            items.add(item);
        }
        discount = Math.rint(discount * 100) / 100d;
        amount = Math.rint(amount * 100) / 100d;
        total = Math.rint(total * 100) / 100d;

    }

    /**
     * 添加商品明细
     *
     * @param product
     * @param
     * @return
     */
    public double addEmpCommissionBeforePay(Product product, int productCount, List<EmployeeCommission> list, Employee employee, OrderItem item) {
        double itemCommission = 0;
        log.info("订单号{}, 操作{}, 操作前订单金额{},操作前提成金额{},操作前折扣金额{}", this.id, "进入无折扣添加订单", this.amount, itemCommission, discount);
        boolean status = false;
        if (product.isOpenTimeEnabled()) {
            itemCommission = judgeTimeRangeEmpBeforePay(list, productCount);
            status = true;
        }
        if (memberId != null && product.isMemberShow() && product.isDisShow() && MyDateUtils.judgeWeek(product.getWeek()) && MyDateUtils.judgeDateSize(product.getNowHours(), product.getTomorrowHour())) {
            if (!status) {
                itemCommission = Math.rint(product.getDisCom() * productCount * 100) / 100d;
            }
            log.info("订单号{}, 操作{}, 操作前订单金额{}, 提成金额{}", this.id, "添加订单进入会员折扣", this.amount, itemCommission);
        } else if (product.isDisShow() && MyDateUtils.judgeWeek(product.getWeek()) && MyDateUtils.judgeDateSize(product.getNowHours(), product.getTomorrowHour())) {
            if (!status) {
                itemCommission = Math.rint(product.getDisCom() * productCount * 100) / 100d;
            }
            log.info("订单号{}, 操作{}, 操作前订单金额{}, 提成金额{},折扣金额{}", this.id, "添加订单进入时间段折扣", this.amount, itemCommission);
        } else if (memberId != null && product.isMemberShow()) {
            if (!status) {
                if (product.isPostEnabled()) {
                    if (employee != null) {
                        itemCommission = Math.rint(product.returnGroupComission(employee.getGroup().getId()) * productCount * 100) / 100d;
                    }
                } else {
                    itemCommission = Math.rint(product.getCommission() * productCount * 100) / 100d;
                }
            }
            log.info("订单号{}, 操作{}, 操作前订单金额{},提成金额{}", this.id, "添加订单进入会员价格折扣", this.amount, itemCommission);
        } else {
            if (!status) {
                if (product.isPostEnabled()) {
                    if (employee != null) {
                        itemCommission = Math.rint(product.returnGroupComission(employee.getGroup().getId()) * productCount * 100) / 100d;
                    }
                } else {
                    itemCommission = Math.rint(product.getCommission() * productCount * 100) / 100d;
                }
            }
        }
        item.setCommission(itemCommission);
        return itemCommission;
    }

    /**
     * 添加商品明细
     *
     * @param product
     * @param orderItemSignUpReq
     * @return
     */
    public void addClerkItem(Product product, OrderItemSignUpReq orderItemSignUpReq, List<EmployeeCommission> list, Employee employee) {
        log.info("订单号{}, 操作{}, 操作前订单金额{},操作前提成金额{},操作前折扣金额{}", this.id, "进入无折扣添加订单", this.amount, commission, discount);
        double price;
        double costPrice;
        double dis = 0.0;
        double original = 0.0;
        double commission = 0;
        boolean status = false;
        if (product.isOpenTimeEnabled()) {
            commission = judgeTimeRange(list);
            status = true;
        }
        if (memberId != null && product.isMemberShow() && product.isDisShow() && MyDateUtils.judgeWeek(product.getWeek()) && MyDateUtils.judgeDateSize(product.getNowHours(), product.getTomorrowHour())) {
            price = Math.rint((product.getDisPrice() * product.getMemberPrice()) * orderItemSignUpReq.getProductCount() * 100) / 100d;
            costPrice = Math.rint(product.getCostPrice() * orderItemSignUpReq.getProductCount() * 100) / 100d;
            dis = Math.rint((product.getSalesPrice() * orderItemSignUpReq.getProductCount() - (product.getDisPrice() * product.getMemberPrice()) * orderItemSignUpReq.getProductCount()) * 100) / 100d;
            original = Math.rint(product.getSalesPrice() * orderItemSignUpReq.getProductCount() * 100) / 100d;
            if (!status) {
                commission = Math.rint(product.getDisCom() * orderItemSignUpReq.getProductCount() * 100) / 100d;
            }
            log.info("订单号{}, 操作{}, 操作前订单金额{}, 提成金额{},折扣金额{}", this.id, "添加订单进入会员折扣", this.amount, commission, dis);
        } else if (product.isDisShow() && MyDateUtils.judgeWeek(product.getWeek()) && MyDateUtils.judgeDateSize(product.getNowHours(), product.getTomorrowHour())) {
            price = Math.rint((product.getDisPrice() * product.getSalesPrice()) * orderItemSignUpReq.getProductCount() * 100) / 100d;
            costPrice = Math.rint(product.getCostPrice() * orderItemSignUpReq.getProductCount() * 100) / 100d;
            dis = Math.rint((product.getSalesPrice() * orderItemSignUpReq.getProductCount() - (product.getDisPrice() * product.getSalesPrice()) * orderItemSignUpReq.getProductCount()) * 100) / 100d;
            original = Math.rint(product.getSalesPrice() * orderItemSignUpReq.getProductCount() * 100) / 100d;
            if (!status) {
                commission = Math.rint(product.getDisCom() * orderItemSignUpReq.getProductCount() * 100) / 100d;
            }
            log.info("订单号{}, 操作{}, 操作前订单金额{}, 提成金额{},折扣金额{}", this.id, "添加订单进入时间段折扣", this.amount, commission, dis);
        } else if (memberId != null && product.isMemberShow()) {
            price = Math.rint(product.getMemberPrice() * orderItemSignUpReq.getProductCount() * 100) / 100d;
            costPrice = Math.rint(product.getCostPrice() * orderItemSignUpReq.getProductCount() * 100) / 100d;
            original = Math.rint(product.getSalesPrice() * orderItemSignUpReq.getProductCount() * 100) / 100d;
            dis = Math.rint(((product.getSalesPrice() * orderItemSignUpReq.getProductCount()) - (product.getMemberPrice() * orderItemSignUpReq.getProductCount())) * 100) / 100d;
            if (!status) {
                if (product.isPostEnabled()) {
                    if (employee != null) {
                        commission = Math.rint(product.returnGroupComission(employee.getGroup().getId()) * orderItemSignUpReq.getProductCount() * 100) / 100d;
                    }
                } else {
                    commission = Math.rint(product.getCommission() * orderItemSignUpReq.getProductCount() * 100) / 100d;
                }
            }
            log.info("订单号{}, 操作{}, 操作前订单金额{},提成金额{},折扣金额{}", this.id, "添加订单进入会员价格折扣", this.amount, commission, dis);
        } else {
            price = Math.rint(product.getSalesPrice() * orderItemSignUpReq.getProductCount() * 100) / 100d;
            costPrice = Math.rint(product.getCostPrice() * orderItemSignUpReq.getProductCount() * 100) / 100d;
            original = Math.rint(product.getSalesPrice() * orderItemSignUpReq.getProductCount() * 100) / 100d;
            if (!status) {
                if (product.isPostEnabled()) {
                    if (employee != null) {
                        double comission = product.returnGroupComission(employee.getGroup().getId());
                        commission = Math.rint(comission * orderItemSignUpReq.getProductCount() * 100) / 100d;
                        log.info("订单号{}, 操作{}, 操作前订单金额{},提成金额{},折扣金额{},是否开启时间段{},该次岗位是{},员工是{}", this.id, "进入无折扣添加订单", this.amount, commission, dis,status,employee.getGroup().getName()+"提成金额是"+comission,employee);
                    }
                } else {
                    commission = Math.rint(product.getCommission() * orderItemSignUpReq.getProductCount() * 100) / 100d;
                }
            }
            log.info("订单号{}, 操作{}, 操作前订单金额{},提成金额{},折扣金额{},是否开启时间段{}", this.id, "进入无折扣添加订单", this.amount, commission, dis,status);
        }
        log.info("门店{}, 订单详情{}, 操作{}, 操作内容{}", product.getStoreId(), items, "添加订单详情", "添加订单详情对应的商品" + product);
        Boolean check = true;
        //查看同类商品是否已选中
        int judgeEnabled = checkSpec(items, orderItemSignUpReq);
        if (judgeEnabled > -1) {
            OrderItem item = items.get(judgeEnabled);
            item.setSalesPrice(item.getSalesPrice() + price);
            item.setDealPrice(item.getDealPrice() + price);
            item.setQuantity(item.getQuantity() + orderItemSignUpReq.getProductCount());
            item.setCostPrice(item.getCostPrice() + costPrice);
            item.setCommission(item.getCommission() + commission);
            item.setMatchEnabled(product.isHaveMatchProductEnabled());
            item.setMobileTag(this.mobileTag);
            check = false;
            item.accuracy();
        }
        //不存在新增订单明细
        if (check) {
            OrderItem item = new OrderItem(UuidUtil.getUuid(), product, orderItemSignUpReq.getProductCount(), commission);
            item.setDealPrice(item.getDealPrice() + price);
            item.setSalesPrice(item.getSalesPrice() + price);
            item.setCostPrice(item.getCostPrice() + costPrice);
            item.setKitchenPrintEnabled(product.isKitchenPrintEnabled());
            item.setLabelEnabled(product.isLabelEnabled());
            item.setIpId(product.getIpId());
            item.setPort(product.getPort());
            item.setIpName(product.getIpName());
            item.setMatchEnabled(product.isHaveMatchProductEnabled());
            item.setIpAddress(product.getIpAddress());
            item.setOpenMatchEnabled(product.isOpenMatchEnabled());
            item.setSpecs(orderItemSignUpReq.getSpecs());
            items.add(item);
            //如果 不存在自定义网费

        }
        amount += price;
        total += original;
        count += orderItemSignUpReq.getProductCount();
        discount += dis;
        this.commission += commission;
        discount = ((int) Math.rint(discount * 100)) / 100d;
        amount = ((int) Math.rint(amount * 100)) / 100d;
        total = ((int) Math.rint(total * 100)) / 100d;
        log.info("订单号{}, 操作{}, 操作前订单金额{},提成金额{},操作后折扣金额{}", this.id, "进入无折扣添加订单", this.amount, commission, discount);

    }

    /**
     * 移除订单明细项
     *
     * @param productId
     * @param price
     * @param quantity
     */
    public OrderItem removeItem(String productId, double price, int quantity, double judgeAmount, boolean deduction, Product product, Employee employee, List<String> specs) {
        OrderItem orderItem = null;
        double dis = 0.0;
        double commission = judgeAmount;
        boolean status = false;
        if (product.isOpenTimeEnabled()) {
            commission = judgeTimeRange(product.getCommissions());
            status = true;
        }
        if (memberId != null && product.isMemberShow() && product.isDisShow() && MyDateUtils.judgeWeek(product.getWeek()) && MyDateUtils.judgeDateSize(product.getNowHours(), product.getTomorrowHour())) {
            price = (product.getDisPrice() * product.getMemberPrice()) * quantity;
            dis = (product.getSalesPrice() * quantity) - (product.getMemberPrice() * product.getDisPrice() * quantity);
            if (!status) {
                commission = Math.rint(product.getDisCom() * quantity * 100) / 100d;
            }
        } else if (product.isDisShow() && MyDateUtils.judgeWeek(product.getWeek()) && MyDateUtils.judgeDateSize(product.getNowHours(), product.getTomorrowHour())) {
            dis = (product.getSalesPrice() * quantity) - (product.getSalesPrice() * product.getDisPrice() * quantity);
            if (!status) {
                commission = product.getDisCom() * quantity;
            }

        } else if (memberId != null && product.isMemberShow()) {
            price = (product.getMemberPrice() * quantity);
            dis = (product.getSalesPrice() * quantity) - (product.getMemberPrice() * quantity);
            if (!status) {
                commission = product.getCommission() * quantity;
            }
        } else {
            if (!status) {
                if (product.isPostEnabled()) {
                    if (employee != null) {
                        commission = Math.rint(product.returnGroupComission(employee.getGroup().getId()) * quantity * 100) / 100d;
                    }
                } else {
                    commission = Math.rint(product.getCommission() * quantity * 100) / 100d;
                }
            }
        }
        //查看同类商品是否已选中
        for (OrderItem item : items) {
            if (StringUtils.equals(item.getProductId(), productId)) {
                if (null != item.getSpecs()) {
                    if (item.getSpecs().size() > 0) {
                        int i = 0;
                        //正常
                        for (String spec : specs) {
                            for (String itemSpec : item.getSpecs()) {
                                if (spec.equals(itemSpec)) {
                                    i += 1;
                                    break;
                                }
                            }
                        }
                        if (i != specs.size()) {
                            continue;
                        }
                    }
                }
                if (quantity > item.getQuantity()) {
                    throw new MyException("修改失败！商品修减数量不足！");
                }

                item.setSalesPrice(item.getSalesPrice() - price);
                item.setDealPrice(item.getDealPrice() - price);
                item.setQuantity(item.getQuantity() - quantity);
                item.setCommission(item.getCommission() - commission);
                if (item.getQuantity() == 0) {
                    item.setEnabled(false);
                }
                if (deduction) {
                    amount -= price;
                    this.commission -= commission;
                } else {
                    discount -= price;
                }
                total -= product.getSalesPrice() * quantity;
                discount -= dis;
                count -= quantity;
                // item.accuracy();
                orderItem = item;
                break;

            }
        }

        discount = ((int) Math.rint(discount * 100)) / 100d;
        amount = ((int) Math.rint(amount * 100)) / 100d;
        total = ((int) Math.rint(total * 100)) / 100d;

        return orderItem;


    }

    public static int checkSpec(List<OrderItem> orderItems, OrderItemSignUpReq orderItemSignUpReq) {
        int index = -1;
        for (int i = 0; i < orderItems.size(); i++) {
            OrderItem item = orderItems.get(i);
            if (item.getProductId().equals(orderItemSignUpReq.getProductId())) {
                if (null != item.getSpecs()) {
                    if (CollectionUtils.isEqualCollection(orderItemSignUpReq.getSpecs(), item.getSpecs())) {
                        return i;
                    }
                } else {
                    return i;
                }
            }
        }
        return index;
    }

    public static int checkDiscountSpec(List<DiscountOrderItem> orderItems, OrderItemSignUpReq orderItemSignUpReq) {
        int index = -1;
        for (int i = 0; i < orderItems.size(); i++) {
            DiscountOrderItem item = orderItems.get(i);
            if (item.getProductId().equals(orderItemSignUpReq.getProductId())) {
                if (null != item.getSpecs()) {
                    if (CollectionUtils.isEqualCollection(orderItemSignUpReq.getSpecs(), item.getSpecs())) {
                        return i;
                    }
                } else {
                    return i;
                }
            }
        }
        return index;
    }

    /**
     * 获取订单所有商品Id
     *
     * @return
     */
    public List<String> getProductIds() {
        List<String> productIds = new ArrayList<>();
        for (OrderItem item : items) {
            productIds.add(item.getProductId());
        }
        return productIds;
    }

    /**
     * 优惠卷使用
     */
    public void handleCoupon(Product product) {


        commission = Math.rint(commission * 100) / 100d;
        discount = ((int) Math.rint(discount * 100)) / 100d;
        amount = ((int) Math.rint(amount * 100)) / 100d;
        total = ((int) Math.rint(total * 100)) / 100d;
    }

    /**
     * 优惠卷取消
     */
    public void relieveCoupon(Product product, double discountAmount, Coupon coupon, double orderCommission) {
        amount = amount + discountAmount;
        discount = discount - discountAmount;
        if (null != coupon) {
            commission = orderCommission;
        }
        commission = Math.rint(commission * 100) / 100d;
        discount = ((int) Math.rint(discount * 100)) / 100d;
        amount = ((int) Math.rint(amount * 100)) / 100d;
        total = ((int) Math.rint(total * 100)) / 100d;
        couponDiscountAmount = 0;
    }


    /**
     * 获取订单状态
     *
     * @return
     */
    public String getStatusMsg() {
        String msg = "订单状态已锁定";
        if (OrderStatus.FINISHED == status || OrderStatus.UNFINISHED == status) {
            msg = "订单已支付";
        } else if (OrderStatus.NOTSURE == status) {
            msg = "订单支付中！请核实！(由于网络原因！如已核实请等待！)";
        } else if (OrderStatus.FAIL == status) {
            msg = "订单支付失败！请重新选择支付方式！";
        }
        return msg;
    }

    /**
     * 轮询提示
     *
     * @return
     */
    public String getMsg() {
        String msg = "";
        if (OrderStatus.FAIL == status) {
            msg = "订单支付失败,请更换支付方式";
        } else if (OrderStatus.CANCELED == status) {
            msg = "订单已取消！";
        }
        return msg;
    }


    /**
     * 判断订单支付状态是否失败
     *
     * @return
     */
    public boolean checkOrderStatusFail() {
        if (status == OrderStatus.NOTSURE &&
                new Date().getTime() - updateTime.getTime() < 1000 * 60 * 10) {
            return true;
        }
        return false;
    }

    /**
     * 判断订单是否为已支付状态
     *
     * @return
     */
    public boolean checkOrderPayStatus() {
        if (status == OrderStatus.UNFINISHED ||
                status == OrderStatus.FINISHED) {
            return true;
        }
        return false;
    }


    /**
     * 判断订单是否可以支付
     *
     * @return
     */
    public boolean checkOrderPay() {
        if (status == OrderStatus.INIT ||
                status == OrderStatus.UNSETTLED ||
                status == OrderStatus.NOTSURE ||
                status == OrderStatus.FAIL) {
            return true;
        }
        return false;
    }

    public boolean checkOrderNeedQueryPay() {
        if (status == OrderStatus.INIT ||
                status == OrderStatus.UNSETTLED ||
                status == OrderStatus.CANCELED ||
                status == OrderStatus.NOTSURE) {
            return true;
        }
        return false;
    }

    /**
     * 订单支付校验
     *
     * @return
     */
    public String payOrderJudge() {
        String msg = null;
        if (amount <= 0) {
            msg = "支付失败！支付金额必须大于0！";
        }
        if (items.size() <= 0) {
            msg = "支付失败！购买商品为空！";
        }
        return msg;
    }

    /**
     * 静态码支付校验
     *
     * @return
     */
    public String staticPayCheck(double amount, PaymentChannel channel) {
        String msg = null;
        if (this.amount != amount) {
            msg = "支付失败！支付金额与订单金额不一致!";
        } else if (total <= 0 && count <= 0) {
            msg = "支付失败！订单总额小于等于0!";
        } else if (type == OrderType.MEMBER_DEPOSIT && StringUtils.isBlank(memberId)) {
            msg = "支付失败！当前订单无会员信息!";
        } else if (channel == PaymentChannel.MEMBER &&
                type == OrderType.MEMBER_DEPOSIT) {
            msg = "支付失败！会员充值不支持会员支付!";
        } else if (status == OrderStatus.FINISHED || status == OrderStatus.UNFINISHED) {
            msg = "订单已支付！请勿重复操作!";
        } else if (status == OrderStatus.REFUNDED) {
            msg = "支付失败！订单已退单!";
        } else if (channel == PaymentChannel.MEMBER && StringUtils.isBlank(memberId)) {
            msg = "支付失败！请添加会员";
        }
        return msg;
    }

    /**
     * 设置订单信息
     *
     * @param scanCodeSignUpReq
     */
    public void setOrderInfo(ScanCodeSignUpReq scanCodeSignUpReq) {
        tableNo = scanCodeSignUpReq.getTableNo();
        notes = scanCodeSignUpReq.getNotes();
    }

    /**
     * 设置订单信息
     *
     * @param paymentSignUpReq
     */
    public void setOrderInfo(PaymentSignUpReq paymentSignUpReq) {
        tableNo = paymentSignUpReq.getTableNo();
        notes = paymentSignUpReq.getNotes();
    }


    /***
     * 校验是否可以更改order
     *
     * @return
     */
    public boolean checkUpdateOrder(int totalFee) {
        int amountInt = (int) Math.rint(amount * 100);
        if (status != OrderStatus.FINISHED &&
                status != OrderStatus.UNFINISHED && amountInt == totalFee) {
            return true;
        }
        return false;
    }


    /**
     * 移除订单明细项
     */
    public void removeOrderItem() {
        List<OrderItem> items1 = new ArrayList<>();
        for (OrderItem item : items) {
            if (!item.isEnabled()) {
                items1.add(item);
            }
        }
        items.removeAll(items1);
    }

    /**
     * 移除订单明细项
     */
    public void removeDiscountOrderItemOut(OrderItem item, int quantity, Product product) {

        if (quantity > item.getQuantity()) {
            throw new MyException("修改失败！商品修减数量不足！");
        }
        item.setSalesPrice(item.getSalesPrice() - product.getSalesPrice() * quantity);
        item.setDealPrice(item.getDealPrice() - product.getSalesPrice() * quantity);
        item.setQuantity(item.getQuantity() - quantity);
        item.setCommission(item.getCommission() - product.getCommission());
        if (item.getQuantity() == 0) {
            item.setEnabled(false);
        }
        amount -= product.getSalesPrice() * quantity;
        this.commission -= product.getCommission();
        total -= product.getSalesPrice() * quantity;
        count -= quantity;
    }

    /**
     * 移除订单明细项
     */
    public void removeDiscountOrderItemIn(OrderItem item, int quantity, Product product, DiscountPromotion discountPromotion, int commission) {
        double price = 0;
        double dis = 0.0;
        if (quantity > item.getQuantity()) {
            throw new MyException("修改失败！商品修减数量不足！");
        }
        if (discountPromotion.getDiscountType().equals(DiscountType.discount)) {
            price += ((product.getSalesPrice() * quantity) * discountPromotion.getDiscount()) / 100;
        } else {
            price += product.getSalesPrice() * quantity - (discountPromotion.getReduceAmount() / 100);
        }
        dis += product.getSalesPrice() * quantity - price;
        item.setSalesPrice(item.getSalesPrice() - product.getSalesPrice() * quantity);
        item.setDealPrice(item.getDealPrice() - price);
        item.setQuantity(item.getQuantity() - quantity);
        item.setCommission(item.getCommission() - commission / 100);
        if (item.getQuantity() == 0) {
            item.setEnabled(false);
        }
        amount -= price;
        this.commission -= commission / 100;
        total -= product.getSalesPrice() * quantity;
        count -= quantity;
        discount -= dis;
    }

    public String checkAddOrder() {
        String msg = null;
        //判断订单状态
        if (status == OrderStatus.UNFINISHED || status == OrderStatus.FINISHED) {
            msg = "订单已支付成功！";
        } else if (status == OrderStatus.REFUNDED) {
            msg = "订单已退！";
        } else if (status == OrderStatus.NOTSURE) {
            msg = "订单支付中，等待支付结果返回。如长时未确定，请退出登录重试";
        }
        return msg;
    }

    public void removeAllOrderItem() {
        List<OrderItem> items1 = new ArrayList<>();
        for (OrderItem item : items) {
            if (item.isEnabled()) {
                items1.add(item);
            }
        }
        items.removeAll(items1);
    }

    public double judgeTimeRange(List<EmployeeCommission> list) {
        double amount = 0;
        for (EmployeeCommission employeeCommission : list) {
            SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
            sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
            String s2 = sdf.format(addTime);
            Long now = Long.parseLong(s2.replace(":", ""));
            Long start = Long.parseLong(employeeCommission.getBegin().replace(":", ""));
            Long over = Long.parseLong(employeeCommission.getEnd().replace(":", ""));
            if (start < now && now < over) {
                amount = employeeCommission.getCommission();
            }
        }
        return amount;
    }

    public double judgeTimeRangeEmpBeforePay(List<EmployeeCommission> list, int productCount) {
        double amount = 0;
        for (EmployeeCommission employeeCommission : list) {
            SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
            sdf.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
            String s2 = sdf.format(addTime);
            Long now = Long.parseLong(s2.replace(":", ""));
            Long start = Long.parseLong(employeeCommission.getBegin().replace(":", ""));
            Long over = Long.parseLong(employeeCommission.getEnd().replace(":", ""));
            if (start < now && now < over) {
                amount = employeeCommission.getCommission() * productCount;
            }
        }
        return amount;
    }


    public boolean addDiscount(Product product, OrderItemSignUpReq orderItemSignUpReq, OrderItem judgeItem, DiscountPromotion discountPromotion, DiscountPromotionProduct promotionProduct) {
        double price = 0;
        double dis = 0.0;
        double commission = 0;
        double original = Math.rint(product.getSalesPrice() * orderItemSignUpReq.getProductCount() * 100) / 100d;
        double costPrice = Math.rint(product.getSalesPrice() * orderItemSignUpReq.getProductCount() * 100) / 100d;
        boolean status = false;


        if (judgeItem == null) {
            DealSameItem dealSameItem = new DealSameItem(product, orderItemSignUpReq, costPrice).invoke();
            price = dealSameItem.getPrice();
            commission = dealSameItem.getCommission();
        } else {
            if (judgeTimeInDiscount(discountPromotion)) {
                if (discountPromotion.getDiscountType().equals(DiscountType.discount)) {
                    if (judgeItem.getQuantity() % 2 == 0) {
                        dis += (((product.getSalesPrice() * ((orderItemSignUpReq.getProductCount()) / 2)) * (100 - discountPromotion.getDiscount())) / 100);
                    } else {
                        if ((orderItemSignUpReq.getProductCount() + 1) % 2 == 0) {
                            dis += (((product.getSalesPrice() * ((orderItemSignUpReq.getProductCount() / 2) + 1) * (100 - discountPromotion.getDiscount())) / 100));
                        } else {
                            dis += (((product.getSalesPrice() * ((orderItemSignUpReq.getProductCount()) / 2)) * (100 - discountPromotion.getDiscount())) / 100);
                        }
                    }
                } else {
                    if (judgeItem.getQuantity() % 2 == 0) {
                        dis += (orderItemSignUpReq.getProductCount() / 2 * (discountPromotion.getReduceAmount() / 100));
                    } else {
                        if ((orderItemSignUpReq.getProductCount() + 1) % 2 == 0) {
                            dis += (((orderItemSignUpReq.getProductCount() / 2) + 1) * (discountPromotion.getReduceAmount() / 100));
                        } else {
                            dis += (orderItemSignUpReq.getProductCount() / 2 * (discountPromotion.getReduceAmount() / 100));
                        }
                    }
                }
                commission += promotionProduct.getDiscountCommission() / 100;
                price += original - dis;
                judgeItem.setSalesPrice(judgeItem.getSalesPrice() + original);
                judgeItem.setDealPrice(judgeItem.getDealPrice() + price);
                judgeItem.setQuantity(judgeItem.getQuantity() + orderItemSignUpReq.getProductCount());
                judgeItem.setCostPrice(judgeItem.getCostPrice() + costPrice);
                judgeItem.setCommission(judgeItem.getCommission() + commission);
                judgeItem.setMobileTag(this.mobileTag);
                judgeItem.accuracy();
                status = true;
            } else {
                commission = product.getCommission() * orderItemSignUpReq.getProductCount();
                price = product.getSalesPrice() * orderItemSignUpReq.getProductCount();
                judgeItem.setSalesPrice(judgeItem.getSalesPrice() + original);
                judgeItem.setDealPrice(judgeItem.getDealPrice() + price);
                judgeItem.setQuantity(judgeItem.getQuantity() + orderItemSignUpReq.getProductCount());
                judgeItem.setCostPrice(judgeItem.getCostPrice() + costPrice);
                judgeItem.setCommission(judgeItem.getCommission() + commission);
                judgeItem.setMobileTag(this.mobileTag);
                judgeItem.accuracy();
            }
        }
        amount += price;
        total += original;
        count += orderItemSignUpReq.getProductCount();
        discount += dis;
        this.commission += commission;
        discount = ((int) Math.rint(discount * 100)) / 100d;
        amount = ((int) Math.rint(amount * 100)) / 100d;
        total = ((int) Math.rint(total * 100)) / 100d;
        return status;
    }


    public boolean judgeTimeInDiscount(DiscountPromotion discountPromotion) {
        if (discountPromotion.getTimeType().equals(TimeType.forever)) {
            if (JodaUtils.judgeWeek(new Date(), discountPromotion.getWeek()) && MyDateUtils.judgeDateSize(discountPromotion.getBeginHour(), discountPromotion.getEndHour()))
                return true;
            return false;
        } else {
            return JodaUtils.judgeDateBetween(discountPromotion.getBeginTime(), discountPromotion.getEndTime(), discountPromotion.getWeek(), discountPromotion.getBeginHour(), discountPromotion.getEndHour());
        }
    }

    public static boolean judgeTimeIn(DiscountPromotion discountPromotion, Date date) {
        if (discountPromotion.getTimeType().equals(TimeType.forever)) {
            if (JodaUtils.judgeWeek(date, discountPromotion.getWeek()) && MyDateUtils.judgeDateSizeEver(discountPromotion.getBeginHour(), discountPromotion.getEndHour(), date))
                return true;
            return false;
        } else {
            return JodaUtils.judgeDateBetweenEver(discountPromotion.getBeginTime(), discountPromotion.getEndTime(), discountPromotion.getWeek(), discountPromotion.getBeginHour(), discountPromotion.getEndHour(), date);
        }
    }



    private class DealSameItem {
        private Product product;
        private OrderItemSignUpReq orderItemSignUpReq;
        private double costPrice;
        private double price;
        private double commission;

        public DealSameItem(Product product, OrderItemSignUpReq orderItemSignUpReq, double costPrice) {
            this.product = product;
            this.orderItemSignUpReq = orderItemSignUpReq;
            this.costPrice = costPrice;
        }

        public double getPrice() {
            return price;
        }

        public double getCommission() {
            return commission;
        }

        public DealSameItem invoke() {
            commission = product.getCommission();
            OrderItem item = new OrderItem(UuidUtil.getUuid(), product, orderItemSignUpReq.getProductCount(), commission);
            price = product.getSalesPrice() * orderItemSignUpReq.getProductCount();
            item.setDealPrice(item.getDealPrice() + price);
            item.setSalesPrice(item.getSalesPrice() + price);
            item.setCostPrice(item.getCostPrice() + costPrice);
            item.setKitchenPrintEnabled(product.isKitchenPrintEnabled());
            item.setLabelEnabled(product.isLabelEnabled());
            item.setIpId(product.getIpId());
            item.setPort(product.getPort());
            item.setIpName(product.getIpName());
            item.setIpAddress(product.getIpAddress());
            item.setSpecs(orderItemSignUpReq.getSpecs());
            items.add(item);
            return this;
        }
    }
}
